<?php
namespace App\Common\Lib\Fun;

class Num {
	
	/**
	 * 保留小数点（不进行四舍五入）
	 * @param float $num 数(小数点左边的整数只支持最多14位数，超过时会出现转换不准确)
	 * @param int $decimals 保留的小数
	 * @param string $decimalpoint 可选。规定用作小数点的字符串。
	 * @param string $separator	 可选。规定用作千位分隔符的字符串。仅使用该参数的第一个字符。比如 "xxx" 仅输出 "x"。注释：如果设置了该参数，那么所有其他参数都是必需的。
	 * @return float
	 */
	public static function numberFormatReal( $num, int $decimals = 0, string $decimalpoint = NULL, string $separator = NULL ){
		$decimals = (int)$decimals;
		$decimals_plus = $decimals + 1;
		$new_num =  sprintf("%.{$decimals}f",substr(sprintf("%.{$decimals_plus}f", $num), 0, -1));
		if( $decimalpoint == NULL && $separator == NULL ) return $new_num;
		if( $decimalpoint != NULL && $separator == NULL ) return number_format( $new_num, $decimals, $decimalpoint );
		if( $separator != NULL ) return number_format( $new_num, $decimals, $decimalpoint, $separator );
	}
	
	/**
	 * 清除多余的小数（如：1.20=>'1.2'）
	 * @param float 清除后的数字
	 */
	public static function clearSurplusDecimals( float $num ){
		return $num;
	}
	
	/**
	 * 生成一定数量的随机数，并且不重复
	 *
	 * @param integer $number 数量
	 * @param integer $length 长度
	 * @param integer $mode 字串类型 0 字母 1 数字 其它 混合
	 * @return string
	 */
	public static function buildCountRand( $number, $length = 4, $mode = 1 ){
		if( $mode == 1 && $length < strlen( $number ) ){
			return false;
		}
		$rand = array();
		for( $i = 0; $i < $number; $i++ ){
			$rand[] = self::randString( $length, $mode );
		}
		$unique = array_unique( $rand );
		if( count( $unique ) == count( $rand ) ){
			return $rand;
		}
		$count = count( $rand ) - count( $unique );
		for( $i = 0; $i < $count * 3; $i++ ){
			$rand[] = self::randString( $length, $mode );
		}
		$rand = array_slice( array_unique( $rand ), 0, $number );
		return $rand;
	}
	
	/**
	 * 获取一定范围内的随机数字 位数不足补零
	 * @param int $min 最小值
	 * @param int $max 最大值
	 * @return int
	 */
	public static function randInt( $min, $max ){
		return mt_rand( $min, $max );
	}

	/**
	 * 获取一定范围内的随机数字 位数不足补零
	 * @param integer $min 最小值
	 * @param integer $max 最大值
	 * @return string
	 */
	public static function randNumber( $min, $max ){
		return sprintf( "%0" . strlen( $max ) . "d", mt_rand( $min, $max ) );
	}

	/**
	 * 小数转百分比
	 * @param int $num 需要转换的数]
	 * @param int $bit 保留的数字
	 * @return string 90%
	 */
	public static function decimalsToPercent( $num, $bit ){
	    $decimals = round( $num, $bit );
	    return  $decimals * 100  . '%';
	}

	/**
	 * 除法(除0等于0)
	 * @param float $a
	 * @param float $b
	 * @return float|int
	 */
	public static function divideOrZero( float $a, float $b ) {
		if( $b == 0 ){
			return 0;
		}
		return $a / $b;
	}

	/**
	 * 检查并返回符合的范围(如果不在范围内则返回最小或最大数)
	 * @param float $value 需要判断的数
	 * @param float|null $min 最小 [null]不限制
	 * @param float|null $max 最大 [null]不限制
	 * @return float 符合的数
	 */
	public static function checkRange( float $value, float|null $min = null, float|null $max = null ):float {
		if( $min !== null && $value < $min ){
			return $min;
		}else if( $max !== null && $value > $max ){
			return $max;
		}else{
			return $value;
		}
	}

	/**
	 * 检查并返回符合的范围(如果不在范围内则返回最小或最大数)
	 * @param int $value 需要判断的数
	 * @param int|null $min 最小 [null]不限制
	 * @param int|null $max 最大 [null]不限制
	 * @return int 符合的数
	 */
	public static function checkRangeAsInt( int $value, int|null $min = null, int|null $max = null ):int {
		if( $min !== null && $value < $min ){
			return intval( $min );
		}else if( $max !== null && $value > $max ){
			return intval( $max );
		}else{
			return intval( $value );
		}
	}

	
}